﻿//-----------------------------------------------------------------------
// <copyright file="Condition.cs" company="LMT">
//     Copyright (c) by La Minh Thuận.
// </copyright>
// <author>thuanla1985@hotmail.com</author>
//-----------------------------------------------------------------------
namespace LMT.Db
{
    /// <summary>
    /// Condition class is used for parsing where query condition.
    /// </summary>
    public class Condition
    {
        /// <summary>
        /// Gets or sets the name of the property.
        /// </summary>
        /// <value>The name of the property.</value>
        public string PropertyName { get; internal set; }

        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>The value.</value>
        public object Value { get; set; }

        /// <summary>
        /// Gets the value2.
        /// </summary>
        public object Value2 { get; set; }

        /// <summary>
        /// Gets or sets the operator.
        /// </summary>
        /// <value>The operator.</value>
        public Operator Compare { get; set; }

        /// <summary>
        /// Gets or sets the and or compare.
        /// </summary>
        /// <value>
        /// The and or compare.
        /// </value>
        public OrAnd AndOrCompare { get; set; }

        /// <summary>
        /// Gets the operator query.
        /// </summary>
        public string OperatorQuery 
        { 
            get 
            {
                switch (this.Compare)
                {
                    case Operator.Equal : return "=";
                    case Operator.NotEqual : return "<>";
                    case Operator.Like : return "LIKE";
                    case Operator.Greater : return ">";
                    case Operator.GreaterOrEqual: return ">=";
                    case Operator.Smaller: return "<";
                    case Operator.SmallerOrEqual: return "<=";
                    case Operator.Between: return "BETWEEN";
                    case Operator.InList: return "IN";
                    case Operator.NotInList: return "NOT IN";
                    case Operator.IsNull: return "IS NULL";
                    default: return string.Empty;
                }
            } 
        }

        /// <summary>
        /// Gets the xor.
        /// </summary>
        public string Xor
        {
            get
            {
                return this.AndOrCompare == OrAnd.And ? "AND" : "OR";
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is compare date only.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is compare date only; otherwise, <c>false</c>.
        /// </value>
        public bool IsCompareDateOnly { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="Condition"/> class.
        /// </summary>
        public Condition()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Condition"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="value">The value.</param>
        /// <param name="opera">The opera.</param>
        public Condition(string property, Operator opera, object value)
        {
            this.PropertyName = property;
            this.Value = value;
            this.Compare = opera;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Condition"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="value">The value.</param>
        /// <param name="opera">The opera.</param>
        /// <param name="isCompareDateOnly">if set to <c>true</c> [is compare date only].</param>
        public Condition(string property, Operator opera, bool isCompareDateOnly, object value)
            : this(property, opera, value)
        {
            this.IsCompareDateOnly = isCompareDateOnly;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Condition"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="opera">The opera.</param>
        /// <param name="isCompareDateOnly">if set to <c>true</c> [is compare date only].</param>
        /// <param name="value">The value.</param>
        /// <param name="xor">The xor.</param>
        public Condition(string property, Operator opera, bool isCompareDateOnly, object value, OrAnd xor)
            : this(property, opera, value)
        {
            this.IsCompareDateOnly = isCompareDateOnly;
            this.AndOrCompare = xor;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Condition"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="opera">The opera.</param>
        /// <param name="isCompareDateOnly">if set to <c>true</c> [is compare date only].</param>
        /// <param name="value1">The value1.</param>
        /// <param name="value2">The value2.</param>
        public Condition(string property, Operator opera, bool isCompareDateOnly, object value1, object value2)
            : this(property, opera, value1)
        {
            this.IsCompareDateOnly = isCompareDateOnly;
            this.Value = value1;
            this.Value2 = value2;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Condition"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="opera">The opera.</param>
        /// <param name="isCompareDateOnly">if set to <c>true</c> [is compare date only].</param>
        /// <param name="value1">The value1.</param>
        /// <param name="value2">The value2.</param>
        /// <param name="xor">The xor.</param>
        public Condition(string property, Operator opera, bool isCompareDateOnly, object value1, object value2, OrAnd xor)
            : this(property, opera, value1)
        {
            this.IsCompareDateOnly = isCompareDateOnly;
            this.Value = value1;
            this.Value2 = value2;
            this.AndOrCompare = xor;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public enum OrAnd : short
    {
        /// <summary>
        /// 
        /// </summary>
        And = 0,
        /// <summary>
        /// 
        /// </summary>
        Or = 1
    }

    /// <summary>
    /// 
    /// </summary>
    public enum Operator : short
    {
        /// <summary>
        /// 
        /// </summary>
        Equal = 0,
        /// <summary>
        /// 
        /// </summary>
        NotEqual = 1,
        /// <summary>
        /// 
        /// </summary>
        Like = 2,
        /// <summary>
        /// 
        /// </summary>
        Greater = 3,
        /// <summary>
        /// 
        /// </summary>
        GreaterOrEqual = 4,
        /// <summary>
        /// 
        /// </summary>
        Smaller = 5,
        /// <summary>
        /// 
        /// </summary>
        SmallerOrEqual = 6,
        /// <summary>
        /// 
        /// </summary>
        Between = 7,
        /// <summary>
        /// 
        /// </summary>
        InList = 8,
        /// <summary>
        /// 
        /// </summary>
        NotInList = 9,
        /// <summary>
        /// 
        /// </summary>
        IsNull = 10
    }
}
